﻿using AntdUI;
using ClosedXML.Excel;
using Serilog;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Reflection;
using System.Xml.Linq;
using WorkTool2.Classes.Data;
using WorkTool2.Classes.Settings;
using WorkTool2.Enums;
using WorkTool2.Helpers;
using WorkTool2.Interfaces;

namespace WorkTool2.Controls
{
    public partial class HolidayStatistics : UserControl, IReload
    {
        private static HCMInfo? _hcmInfo = null;

        private Form form;

        public HolidayStatistics(Form _form)
        {
            form = _form;
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            try
            {
                base.OnLoad(e);
                ITask.Run(() =>
                {
                    calendar.ShowButtonToDay = false;
                    calendar.Full = true;
                    holiday_table.Columns = [];
                    var properties = typeof(HolidayStatisticsData).GetProperties(BindingFlags.Public | BindingFlags.Instance);
                    foreach (var property in properties)
                    {
                        var descriptionAttr = property.GetCustomAttribute<DescriptionAttribute>();
                        if (descriptionAttr != null)
                        {
                            holiday_table.Columns.Add(new Column(property.Name, descriptionAttr.Description, ColumnAlign.Center).SetEllipsis().SetMaxWidth("50%"));
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                Log.Error(ex, ex.Message);
            }
        }

        public void Reload()
        {
            if (_hcmInfo != null && (!_hcmInfo.Username.Equals(SettingsHelper._holidayStatisticsSettings.Username) || !_hcmInfo.Password.Equals(SettingsHelper._holidayStatisticsSettings.Password)))
                _hcmInfo = null;
        }

        private void button_Click(object sender, EventArgs e)
        {
            Spin.open(form, "正在处理中，请耐心等候...",
                config =>
               {
                   Task.Run(async () =>
                   {
                       try
                       {
                           DateTime? date = null;
                           switch (select.SelectedIndex)
                           {
                               case 0:
                                   break;

                               case 1:
                                   date = DateTime.Now;
                                   break;

                               case 2:
                                   date = DateTime.Now.Date.AddMonths(-1);
                                   break;

                               case 3:
                                   if (string.IsNullOrEmpty(datePicker.Text.Trim()))
                                   {
                                       Modal.open(form, "错误", "请选择或输入要查询的月份", TType.Error);
                                       return;
                                   }
                                   date = DateTime.Parse(datePicker.Text.Trim());
                                   break;

                               default:
                                   Modal.open(form, "错误", "请选择或输入要查询的月份", TType.Error);
                                   return;
                           }
                           if (!await VerifyLogin(SettingsHelper._holidayStatisticsSettings, true))
                               return;
                           config.Text = "正在查询假期结余...";
                           if (!await GetHolidayBalance())
                           {
                               if (!await VerifyLogin(SettingsHelper._holidayStatisticsSettings, false))
                                   return;
                               await GetHolidayBalance();
                           }
                           config.Text = "正在查询请假记录...";
                           var myHolidayStatisticsList = await GetHolidayStatistics(date);
                           holiday_table.DataSource = myHolidayStatisticsList;
                           var lunchAllowanceStatisticsList = new List<LunchAllowanceStatistics>();
                           var calendarDate = new List<CalendarData>();
                           var calendarYear = new List<DateTime>();
                           if (date.HasValue)
                               calendarYear.Add(date.Value);
                           calendarYear.AddRange(myHolidayStatisticsList.Select(x => x.StartTime.Date));
                           calendarYear.AddRange(myHolidayStatisticsList.Select(x => x.EndTime.Date));
                           foreach (var year in calendarYear.Select(x => x.Year).Distinct())
                           {
                               var temp = CalendarHelper.GetCalendarSettings(year);
                               if (temp.Count == 0)
                                   temp = await GetHcmCalendarData(year);
                               calendarDate.AddRange(temp);
                           }
                           foreach (var myHolidayStatistics in myHolidayStatisticsList)
                           {
                               for (var day = myHolidayStatistics.StartTime.Date; day <= myHolidayStatistics.EndTime.Date; day = day.AddDays(1))
                               {
                                   var calendarDay = calendarDate.Where(x => x.Date.Equals(day)).ToList();
                                   if (calendarDay.Count > 0)
                                   {
                                       if (calendarDay.Any(x => x.CalendarDateStatus.Equals(CalendarDateStatus.DayOff)))
                                           continue;
                                   }
                                   else
                                   {
                                       if ((int)day.DayOfWeek == 0 || (int)day.DayOfWeek == 6)
                                           continue;
                                   }
                                   var tempStart = day > myHolidayStatistics.StartTime ? day.AddHours(9) : myHolidayStatistics.StartTime;
                                   var tempEnd = day.Date < myHolidayStatistics.EndTime.Date ? day.AddHours(18) : myHolidayStatistics.EndTime;
                                   var myCalendarData = new CalendarData
                                   {
                                       Date = day,
                                       CalendarDateStatus = CalendarDateStatus.Leave,
                                       CalendarLeaveData = new CalendarLeaveData { LeaveName = myHolidayStatistics.LeaveName }
                                   };
                                   if (tempStart.Hour <= 9 && tempEnd.Hour >= 17)
                                       myCalendarData.CalendarLeaveData.LeaveTimeType = LeaveTimeType.All;
                                   else
                                   if (tempStart.Hour <= 9 && tempEnd.Hour < 17)
                                       myCalendarData.CalendarLeaveData.LeaveTimeType = LeaveTimeType.AM;
                                   else
                                   if (tempStart.Hour > 9)
                                       myCalendarData.CalendarLeaveData.LeaveTimeType = LeaveTimeType.PM;
                                   calendarDate.Add(myCalendarData);
                                   lunchAllowanceStatisticsList.Add(new LunchAllowanceStatistics
                                   {
                                       Day = day.Day,
                                       CalendarDateStatus = CalendarDateStatus.Leave,
                                       LeaveName = myHolidayStatistics.LeaveName == "年假" ? "年休假" : myHolidayStatistics.LeaveName,
                                       LeaveTime = myCalendarData.CalendarLeaveData.LeaveTimeType
                                   });
                               }
                           }
                           config.Text = "正在生成日历...";
                           CreateCalendar(date, calendarDate);
                           config.Text = "";
                           if (date.HasValue)
                           {
                               if (Modal.open(new Modal.Config(form, "提示", "是否生成午餐津贴统计表？", TType.Info)
                               {
                                   CancelText = "否",
                                   OkText = "是"
                               }) == DialogResult.OK)
                               {
                                   ExportReport(date.Value, calendarDate, lunchAllowanceStatisticsList, _hcmInfo.UserCode);
                               }
                           }
                       }
                       catch (Exception ex)
                       {
                           Notification.error(form, "查询失败", ex.Message, AntdUI.TAlignFrom.Top);
                           Log.Error(ex, ex.Message);
                       }
                   }).Wait();
               },
                () => { }
            );
        }

        private void select_SelectedValueChanged(object sender, ObjectNEventArgs e)
        {
            datePicker.Visible = e.Value.ToString() == "自定义";
        }

        private async Task<bool> VerifyLogin(HolidayStatisticsSettings holidayStatisticsSettings, bool getHolidayBalance)
        {
            if (_hcmInfo == null || !_hcmInfo.Username.Equals(holidayStatisticsSettings.Username) || !_hcmInfo.Password.Equals(holidayStatisticsSettings.Password) || !getHolidayBalance)
            {
                var result = new HCMInfo()
                {
                    Username = holidayStatisticsSettings.Username,
                    Password = holidayStatisticsSettings.Password
                };
                using var client = new HttpClient();
                var tokenRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx")
                {
                    Content = new StringContent($"<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"Login\" Method=\"LoginByUserCodePwd\" Language=\"Chinese\" UserCode=\"{holidayStatisticsSettings.Username}\" LoginUserCode=\"\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/\" StartHandlerIndex=\"0\"><Parameters><String>{holidayStatisticsSettings.Username}</String><String>{holidayStatisticsSettings.Password.CalculateMD5().CalculateMD5()}</String><String/><String/><null/><String/></Parameters></Message>", null, "application/xml")
                };
                var tokenResponse = await client.SendAsync(tokenRequest);
                tokenResponse.EnsureSuccessStatusCode();
                var tokenString = await tokenResponse.Content.ReadAsStringAsync();
                var tokenXml = XDocument.Parse(tokenString);
                var message = tokenXml.Descendants("ReturnData").Elements("String").Where(x => x.Attribute("Name")?.Value == "info").FirstOrDefault().Value;
                if (string.IsNullOrEmpty(message))
                {
                    result.TokenId = tokenXml.Descendants("String").FirstOrDefault(e => (string)e.Attribute("Name") == "tokenId")?.Value;
                    result.UserId = tokenXml.Descendants("String").FirstOrDefault(e => (string)e.Attribute("Name") == "userId")?.Value;
                    result.UserCode = tokenXml.Descendants("String").FirstOrDefault(e => (string)e.Attribute("Name") == "userCode")?.Value;
                    _hcmInfo = result;
                    return true;
                }
                else
                {
                    Modal.open(form, "错误", message, TType.Error);
                    return false;
                }
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 查询假期结余
        /// </summary>
        /// <returns></returns>
        private async Task<bool> GetHolidayBalance()
        {
            using var client = new HttpClient();
            var holidayBalanceMessage = $"<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"AnnualLeave\" Method=\"GetPersonalLeaveInfo\" Language=\"Chinese\" UserCode=\"{_hcmInfo.UserCode}\" LoginUserCode=\"{_hcmInfo.UserCode}\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/Home/MyPaidLeaveInfo\" StartHandlerIndex=\"0\"><Parameters><String>{_hcmInfo.UserId}</String></Parameters></Message>";
            var holidayBalanceRequestHash = (holidayBalanceMessage.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var holidayBalanceRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx?MessageHash=" + holidayBalanceRequestHash)
            {
                Content = new StringContent(holidayBalanceMessage)
            };
            var holidayBalanceResponse = await client.SendAsync(holidayBalanceRequest);
            holidayBalanceResponse.EnsureSuccessStatusCode();
            var holidayBalanceString = await holidayBalanceResponse.Content.ReadAsStringAsync();
            var holidayBalanceXml = XDocument.Parse(holidayBalanceString);
            var anlvInfo = holidayBalanceXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "anlvInfo");
            var dt = new DataTable();
            var distribution = dt.NewRow();
            var balance = dt.NewRow();
            dt.Columns.Add("假期名称");
            distribution["假期名称"] = "发放";
            balance["假期名称"] = "结余";
            if (anlvInfo != null)
            {
                var columns = anlvInfo.Element("Columns")?.Elements("Column").Select(col => col.Attribute("Name")?.Value ?? "UnnamedColumn").ToList();
                dt.Columns.Add("年假");
                var values = anlvInfo.Element("Rows")?.Elements("Row").Elements().ToList();
                var canUseCurYear = decimal.Parse(values[columns.IndexOf("canUseCurYear")].Value);
                var restNextYear = canUseCurYear - 10;
                distribution["年假"] = $"(本年){canUseCurYear.ToString().HolidayNum()} + (上年){values[columns.IndexOf("restLastYear")].Value.HolidayNum()} = {values[columns.IndexOf("entitlement")].Value.HolidayNum()}";
                balance["年假"] = $"{values[columns.IndexOf("restCurYear")].Value.HolidayNum()} (可带到下一年天数：{(restNextYear > 0 ? restNextYear.ToString().HolidayNum() : canUseCurYear.ToString().HolidayNum())})";
            }
            var otherInfo = holidayBalanceXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "otherInfo");
            if (anlvInfo == null && otherInfo == null)
                return false;
            if (otherInfo != null)
            {
                var columns = otherInfo.Element("Columns")?.Elements("Column").Select(col => col.Attribute("Name")?.Value ?? "UnnamedColumn").ToList();
                var holidayName = columns.IndexOf("c_name");
                var holidayDistribution = columns.IndexOf("canUseCurYear");
                var holidayBalance = columns.IndexOf("restBalance");
                foreach (var row in otherInfo.Element("Rows")?.Elements("Row").ToList())
                {
                    var values = row.Elements().ToList();
                    dt.Columns.Add(values[holidayName].Value);
                    distribution[values[holidayName].Value] = values[holidayDistribution].Value.HolidayNum();
                    balance[values[holidayName].Value] = values[holidayBalance].Value.HolidayNum();
                }
            }
            dt.Rows.Add(distribution);
            dt.Rows.Add(balance);
            balance_table.DataSource = dt;
            return true;
        }

        /// <summary>
        /// 查询请假记录
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private async Task<List<CalendarData>> GetHcmCalendarData(int year)
        {
            using var client = new HttpClient();
            var calendarDataList = new List<CalendarData>();
            var holidayCalendarMessage = $"<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"YearAtt\" Method=\"GetHughClassListByUseridAndDate\" Language=\"Chinese\" UserCode=\"{_hcmInfo.UserCode}\" LoginUserCode=\"{_hcmInfo.UserCode}\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/Home/MyCalendar\" StartHandlerIndex=\"0\"><Parameters><String>{_hcmInfo.UserId}</String><DateTime>{year}-01-01 00:00:00</DateTime><DateTime>{year}-12-31 23:59:59</DateTime></Parameters></Message>";
            var holidayCalendarRequestHash = (holidayCalendarMessage.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var holidayCalendarRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx?MessageHash=" + holidayCalendarRequestHash)
            {
                Content = new StringContent(holidayCalendarMessage)
            };
            var holidayCalendarResponse = await client.SendAsync(holidayCalendarRequest);
            holidayCalendarResponse.EnsureSuccessStatusCode();
            var holidayCalendarString = await holidayCalendarResponse.Content.ReadAsStringAsync();
            var holidayCalendarXml = XDocument.Parse(holidayCalendarString);
            var holidayCalendar = holidayCalendarXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "ReturnData");
            if (holidayCalendar != null)
            {
                foreach (var row in holidayCalendar.Element("Rows")?.Elements("Row").ToList())
                {
                    var values = row.Elements().ToList();
                    var type = int.Parse(values[1].Value);
                    var day = DateTime.Parse(values[0].Value).Date;
                    var calendarData = new CalendarData
                    {
                        Date = day
                    };
                    switch (type)
                    {
                        case 0:
                        case 1:
                            calendarData.CalendarDateStatus = CalendarDateStatus.DayOff;
                            break;

                        case 2:
                            calendarData.CalendarDateStatus = CalendarDateStatus.WorkingDays1;
                            break;

                        default:
                            break;
                    }
                    calendarDataList.Add(calendarData);
                }
            }
            return calendarDataList;
        }

        /// <summary>
        /// 查询请假记录
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private async Task<List<HolidayStatisticsData>> GetHolidayStatistics(DateTime? date)
        {
            var leaveResultList = new List<HolidayStatisticsData>();
            using var client = new HttpClient();
            var leaveMessage = "<Message ID=\"msg1\" MessageType=\"InvokeServiceMessage\" Service=\"Workflow\" Method=\"{0}\" Language=\"Chinese\" UserCode=\"{1}\" LoginUserCode=\"{1}\" TokenID=\"\" ClientType=\"Web\" ShellPlatform=\"Browser\" URL=\"/Home/myApplicationList\" StartHandlerIndex=\"0\"><Parameters><Dictionary><Int Name=\"start\">0</Int><Int Name=\"limit\">99999</Int><String Name=\"sort\">createtime desc</String><String Name=\"filter\"/><String Name=\"currentUserId\">{2}</String><Int Name=\"page\">1</Int><String Name=\"searchemp\"/><String Name=\"searchkeyword\"/><null Name=\"createtimefrom\"/><null Name=\"createtimeto\"/>";
            if (date.HasValue)
            {
                var firstDayOfMonth = new DateTime(date.Value.Year, date.Value.Month, 1);
                var lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);
                leaveMessage += $"<DateTime Name=\"starttimefrom\">{firstDayOfMonth:yyyy-MM-dd} 00:00:00</DateTime><DateTime Name=\"starttimeto\">{lastDayOfMonth:yyyy-MM-dd} 23:59:59</DateTime>";
            }
            else
            {
                leaveMessage += "<null Name=\"starttimefrom\"/><null Name=\"starttimeto\"/>";
            }
            leaveMessage += "<String Name=\"processtype\">wfmleave</String><Bool Name=\"queryhistory\">false</Bool></Dictionary></Parameters></Message>";
            var waitingRequest = string.Format(leaveMessage, "GetMyWaitingProcessWithBizData", _hcmInfo.UserCode, _hcmInfo.UserId);
            var waitingRequestHash = (waitingRequest.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var completedRequest = string.Format(leaveMessage, "GetMyCompletedProcessWithBizData", _hcmInfo.UserCode, _hcmInfo.UserId);
            var completedRequestHash = (completedRequest.EscapeDataString() + _hcmInfo.TokenId).CalculateMD5();
            var leaveRequestDic = new Dictionary<string, string> {
                            { waitingRequestHash, waitingRequest },
                            { completedRequestHash, completedRequest },
                        };
            foreach (var item in leaveRequestDic)
            {
                var leaveRequest = new HttpRequestMessage(HttpMethod.Get, "https://wfm.platinumchina.com/workforce/Handlers/MobileHandler.ashx?MessageHash=" + item.Key)
                {
                    Content = new StringContent(item.Value)
                };
                var leaveResponse = await client.SendAsync(leaveRequest);
                leaveResponse.EnsureSuccessStatusCode();
                var leaveString = await leaveResponse.Content.ReadAsStringAsync();
                var leaveXml = XDocument.Parse(leaveString);
                var mainDataTable = leaveXml.Descendants("DataTable").FirstOrDefault(dt => dt.Attribute("Name")?.Value == "$");
                if (mainDataTable != null)
                {
                    var columns = mainDataTable.Element("Columns")?.Elements("Column")
                                             .Select((col, index) => new
                                             {
                                                 Name = col.Attribute("Name")?.Value,
                                                 DataType = col.Attribute("DataType")?.Value,
                                                 Index = index
                                             })
                                             .ToList();
                    var rows = mainDataTable.Element("Rows")?.Elements("Row");
                    if (columns != null && rows != null)
                    {
                        foreach (var row in rows)
                        {
                            var rowDict = new Dictionary<string, string>();
                            foreach (var column in columns)
                            {
                                if (string.IsNullOrEmpty(column.Name)) continue;
                                var element = row.Elements().ElementAt(column.Index);
                                rowDict[column.Name] = element.Value;
                            }
                            if (rowDict["processresult"] != "Rejected")
                            {
                                leaveResultList.Add(new HolidayStatisticsData
                                {
                                    LeaveName = rowDict["biz_leavename_c"],
                                    ApplyNums = rowDict["biz_applynums"],
                                    UnitName = rowDict["biz_unitcnname"],
                                    StartTime = DateTime.Parse(rowDict["starttime"]),
                                    EndTime = DateTime.Parse(rowDict["biz_enddate"]),
                                    Status = rowDict["status"] == "Started" ? "审批中" : "已完成"
                                });
                            }
                        }
                    }
                }
            }
            return leaveResultList;
        }

        /// <summary>
        /// 导出午餐津贴统计表
        /// </summary>
        /// <param name="date"></param>
        /// <param name="calendarDate"></param>
        /// <param name="lunchAllowanceStatisticsList"></param>
        private void ExportReport(DateTime date, List<CalendarData> calendarDate, List<LunchAllowanceStatistics> lunchAllowanceStatisticsList, string signature)
        {
            var firstDayOfMonth = date.AddDays(1 - date.Day);
            var daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);
            var currentDay = 1;
            while (currentDay <= daysInMonth)
            {
                if (!lunchAllowanceStatisticsList.Any(x => x.Day.Equals(currentDay)))
                {
                    var day = new DateTime(date.Year, date.Month, currentDay);
                    var lunchAllowanceStatistics = new LunchAllowanceStatistics
                    {
                        Day = currentDay,
                        CalendarDateStatus = ((int)day.DayOfWeek == 0 || (int)day.DayOfWeek == 6) ? CalendarDateStatus.DayOff : CalendarDateStatus.WorkingDays,
                    };
                    var temp = calendarDate.FirstOrDefault(x => x.Date.Equals(day));
                    if (temp != null)
                    {
                        lunchAllowanceStatistics.CalendarDateStatus = temp.CalendarDateStatus;
                    }
                    lunchAllowanceStatisticsList.Add(lunchAllowanceStatistics);
                }
                currentDay++;
            }
            using var workbook = new XLWorkbook(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "LunchAllowanceStatisticsTemplate.xlsx"));
            var codesheet = workbook.Worksheet(2);
            var leaveCodeList = new List<LeaveTypeCode>();
            foreach (var row in codesheet.RowsUsed().Skip(1))
            {
                leaveCodeList.Add(new LeaveTypeCode()
                {
                    Code = row.Cell(1).Value.ToString(),
                    Description = row.Cell(2).Value.ToString()
                });
            }
            var worksheet = workbook.Worksheet(1);
            worksheet.Cell(11, 2).SetValue($"{ToolHelper._month[date.ToString("MM")]} 1-{ToolHelper._month[date.ToString("MM")]} {lunchAllowanceStatisticsList.Count},{date:yyyy}");
            var rowIndex = 16;
            int allowanceDay = 0;
            double workDay = 0;
            foreach (var item in lunchAllowanceStatisticsList.OrderBy(x => x.Day).GroupBy(x => x.Day))
            {
                worksheet.Cell(rowIndex, 1).SetValue(item.Key);
                var remarks = new List<string>();
                var allowance = "Y";
                foreach (var l in item)
                {
                    if (l.Allowance.Equals("N"))
                        allowance = l.Allowance;
                    if (l.LeaveTime.HasValue)
                    {
                        var remark = string.Empty;
                        switch (l.LeaveTime.Value)
                        {
                            case LeaveTimeType.All:
                                remark = l.LeaveName + "（全天）";
                                break;

                            case LeaveTimeType.AM:
                                remark = "上午" + l.LeaveName;
                                break;

                            case LeaveTimeType.PM:
                                remark = "下午" + l.LeaveName;
                                break;

                            default:
                                break;
                        }
                        remarks.Add(remark);
                    }
                }
                var tempAllowance = item.Any(x => x.Allowance.Equals("N")) ? "N" : "Y";
                if (tempAllowance == "Y")
                {
                    allowanceDay++;
                    workDay = remarks.Count > 0 ? (workDay + 0.5) : (workDay + 1);
                }
                worksheet.Cell(rowIndex, 2).SetValue(tempAllowance);
                switch (SettingsHelper._holidayStatisticsSettings.AllowanceRemarks)
                {
                    case 1:
                        if (allowance.Equals("Y") && remarks.Count == 0)
                            remarks.Add("出勤");
                        break;

                    case 2:
                        break;

                    case 3:
                        if (remarks.Count == 1 && remarks.Any(x => x.Contains("下午")))
                            remarks = [];
                        break;

                    default:
                        break;
                }
                if (remarks.Count > 0)
                {
                    var remark = string.Join("/", remarks.Distinct());

                    if (!string.IsNullOrEmpty(remark))
                        worksheet.Cell(rowIndex, 3).SetValue(leaveCodeList.FirstOrDefault(x => x.Description.Equals(remark))?.Code);
                }
                if (item.First().CalendarDateStatus.Equals(CalendarDateStatus.DayOff))
                    worksheet.Row(rowIndex).Cells(1, 3).Style.Fill.SetBackgroundColor(XLColor.FromArgb(250, 191, 143));
                rowIndex++;
            }
            worksheet.Cell(47, 2).FormulaA1 = $"=COUNTIF(B16:B{rowIndex - 1},\"Y\")";
            worksheet.Cell(48, 2).SetValue(signature);
            if (rowIndex <= 46)
                worksheet.Rows(rowIndex, 46).Delete();
            workbook.RecalculateAllFormulas();
            var fileRemark = $"预估津贴：{allowanceDay} * 15 = {(allowanceDay * 15)} 元（请准备大于等于{(allowanceDay * 15)}元的发票）\n预估工时：{workDay} * 8 = {(workDay * 8)} 小时";
            var filePath = Path.Combine(SettingsHelper._fileSettings.SaveFolder, $"午餐津贴统计表 {ToolHelper._month[date.ToString("MM")]}.,{date:yyyy}_{signature}{(SettingsHelper._fileSettings.SaveFileNameRandom ? $"_{new Random().Next(10000, 99999)}" : "")}.xlsx");
            workbook.SaveAs(filePath);
            if (new Modal.Config(form, "是否打开文件？", $"{fileRemark}\n\n文件已保存至：{filePath}", TType.Success)
            {
                OnButtonStyle = (id, btn) =>
                {
                    btn.BackExtend = "135, #6253E1, #04BEFE";
                },
                CancelText = "否",
                OkText = "是"
            }.open() == DialogResult.OK)
            {
                Process.Start(new ProcessStartInfo
                {
                    FileName = filePath,
                    UseShellExecute = true
                });
            }
            (form as Main).AddHistoryData(new HistoryData("假期查询 & 津贴生成", filePath, fileRemark)).ConfigureAwait(false);
        }

        /// <summary>
        /// 创建日历
        /// </summary>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="calendarData">日历填充数据</param>
        private void CreateCalendar(DateTime? date, List<CalendarData> calendarDataList)
        {
            calendarDataList ??= [];
            if (date.HasValue)
            {
                var startDate = new DateTime(date.Value.Year, date.Value.Month, 1, 0, 0, 0);
                var endDate = startDate.AddMonths(1).AddDays(-1).AddHours(23).AddMinutes(59).AddSeconds(59);
                calendar.SetMinMax(startDate, endDate);
            }
            else
            {
                calendar.MinDate = DateTime.Now;
                calendar.MaxDate = DateTime.Now;
                calendar.Invalidate();
                calendar.MinDate = null;
                calendar.MaxDate = null;
            }
            calendar.Invalidate();
            calendar.BadgeAction = dates =>
            {
                var result = new List<DateBadge>();

                for (DateTime day = dates[0].Date; day <= dates[1].Date; day = day.AddDays(1))
                {
                    var dayData = calendarDataList.Where(x => x.Date.Equals(day)).OrderBy(x => x.CalendarDateStatus).FirstOrDefault();
                    if (dayData != null)
                    {
                        Color color = Color.YellowGreen;
                        var description = "";
                        switch (dayData.CalendarDateStatus)
                        {
                            case CalendarDateStatus.WorkingDays:
                                break;

                            case CalendarDateStatus.WorkingDays1:
                                color = Color.OrangeRed;
                                description = dayData.Description;
                                break;

                            case CalendarDateStatus.DayOff:
                                description = dayData.Description;
                                break;

                            case CalendarDateStatus.Custom:
                                description = dayData.Description;
                                color = Color.DarkBlue;
                                break;

                            case CalendarDateStatus.Leave:
                                color = Color.Orange;
                                description = dayData.CalendarLeaveData.LeaveName + " " + (dayData.CalendarLeaveData.LeaveTimeType.Equals(LeaveTimeType.All) ? "" : dayData.CalendarLeaveData.LeaveTimeType.ToString());
                                break;

                            default:
                                break;
                        }
                        result.Add(new DateBadge(day.ToString("yyyy-MM-dd"), description, color));
                    }
                    else
                    {
                        if ((int)day.DayOfWeek == 0 || (int)day.DayOfWeek == 6)
                        {
                            result.Add(new DateBadge(day.ToString("yyyy-MM-dd"), "休", Color.YellowGreen));
                        }
                    }
                }
                return result;
            };
            calendar.LoadBadge();
        }

        private Table.CellStyleInfo? table_SetRowStyle(object sender, TableSetRowStyleEventArgs e)
        {
            if (e.Index % 2 == 0)
            {
                return new Table.CellStyleInfo
                {
                    BackColor = Config.IsDark ? Color.Gray : Color.WhiteSmoke,
                };
            }
            return null;
        }
    }
}